// fetch-client.js
import { fetch } from "@tauri-apps/plugin-http"

const RequestStatus = {
    SUCCESS: "success",
    ERROR: "error",
    TIMEOUT: "timeout",
}

const DEFAULT_CONFIG = {
    timeout: 30000,
    credentials: "same-origin",
    headers: {
        "Content-Type": "application/json",
    },
}

export async function enhancedFetch(url, options = {}) {
    const startTime = Date.now()
    const finalOptions = {
        ...DEFAULT_CONFIG,
        ...options,
        headers: {
            ...DEFAULT_CONFIG.headers,
            ...options.headers,
        },
    }

    const requestInfo = {
        url,
        method: finalOptions.method || "GET",
        headers: finalOptions.headers,
        body: finalOptions.body,
    }

    try {
        const timeoutPromise = new Promise((resolve) => {
            setTimeout(() => resolve("TIMEOUT"), finalOptions.timeout)
        })

        const fetchPromise = fetch(url, finalOptions)
        const response = await Promise.race([fetchPromise, timeoutPromise])

        if (response === "TIMEOUT") {
            throw new Error(`Request timeout after ${finalOptions.timeout}ms`)
        }

        const responseInfo = {
            status: response.status,
            statusText: response.statusText,
            headers: Object.fromEntries(response.headers.entries()),
            type: response.type,
            url: response.url,
            redirected: response.redirected,
            ok: response.ok,
        }

        const { body, bodyInfo } = await parseResponseBody(response)

        return {
            status: RequestStatus.SUCCESS,
            requestInfo,
            responseInfo: {
                ...responseInfo,
                body,
                bodyInfo,
            },
            duration: Date.now() - startTime,
        }
    } catch (error) {
        return {
            status: error.message.includes("timeout") ? RequestStatus.TIMEOUT : RequestStatus.ERROR,
            requestInfo,
            error: {
                message: error.message,
                stack: error.stack,
            },
            duration: Date.now() - startTime,
        }
    }
}

async function parseResponseBody(response) {
    const contentType = response.headers.get("content-type")
    const contentLength = response.headers.get("content-length")
    let body
    let bodyInfo = {
        type: contentType,
        size: contentLength,
        encoding: response.headers.get("content-encoding"),
    }

    // 检查是否为流式响应
    if (response.headers.get("transfer-encoding") === "chunked" || contentType?.includes("text/event-stream")) {
        bodyInfo.format = "stream"

        try {
            // 创建一个新的 ReadableStream
            const stream = new ReadableStream({
                async start(controller) {
                    const reader = response.body.getReader()
                    const decoder = new TextDecoder()
                    let buffer = ""

                    try {
                        while (true) {
                            const { done, value } = await reader.read()

                            if (done) {
                                // 处理缓冲区中剩余的数据
                                if (buffer.trim()) {
                                    controller.enqueue(buffer.trim())
                                }
                                break
                            }

                            // 解码数据
                            const text = decoder.decode(value, { stream: true })
                            buffer += text

                            // 按行分割并发送
                            const lines = buffer.split("\n")
                            // 保留最后一个可能不完整的行
                            buffer = lines.pop() || ""

                            // 发送完整的行
                            for (const line of lines) {
                                if (line.trim()) {
                                    controller.enqueue(line.trim())
                                }
                            }
                        }
                    } catch (error) {
                        controller.error(error)
                    } finally {
                        controller.close()
                    }
                },
            })

            return {
                body: stream,
                bodyInfo: {
                    ...bodyInfo,
                    format: "stream",
                    streaming: true,
                },
            }
        } catch (error) {
            console.error("Stream processing error:", error)
            throw error
        }
    }
    // 处理常规响应
    if (contentType?.includes("application/json")) {
        body = await response.json()
        bodyInfo.format = "json"
    } else if (contentType?.includes("text/")) {
        body = await response.text()
        bodyInfo.format = "text"
    } else {
        const buffer = await response.arrayBuffer()
        body = buffer
        bodyInfo.format = "binary"
        bodyInfo.size = buffer.byteLength
    }

    return { body, bodyInfo }
}

export const fetchUtils = {
    RequestStatus,
    DEFAULT_CONFIG,
}
